/// <reference path="../../../libs/wx.d.ts" />

namespace mgp.ads {
    export class WxBannerAd implements IBannerAd {

        protected _bannerAd: wx.BannerAd;

        create(obj: IBannerAdObj) {
            throw new Error("Method not implemented.");
        }
        show() {
            throw new Error("Method not implemented.");
        }
        hide() {
            throw new Error("Method not implemented.");
        }
        destroy() {
            throw new Error("Method not implemented.");
        }

        protected _systemInfo: _getSystemInfoSyncReturnValue;
        protected _crtAdIdx = -1;

        /** 倒计时用的handler */
        protected _timeKey: number = 0;

        protected _bannerShowing = false;
        protected _justShowByLongPhone = false;
        protected _bannerLoaded = false;// banner是否加载完成
        /** 准备要手动显示banner，如果调用了hide，就要设置为false，防止加载太久后显示 */
        protected _readyShowBanner = false;
        protected _crtResize: (res: any) => { left: number, top: number };

        protected _isLongPhone() {
            let info = this._getSystemInfoSync();
            if (info && info.windowHeight && info.windowWidth) {
                return info.windowHeight / info.windowWidth > 1.85
            }
            return false;
        }
        protected _getSystemInfoSync(): _getSystemInfoSyncReturnValue {
            if (this._systemInfo) {
                return this._systemInfo;
            }
            this._systemInfo = wx.getSystemInfoSync() as _getSystemInfoSyncReturnValue;
            return this._systemInfo
        }
        protected _onIOS() {
            let info = this._getSystemInfoSync();
            if (info && info.system && info.system.indexOf('iOS') > -1) {
                return true;
            }
            return false;
        }

        showBannerAd(justShowByLongPhone?: boolean, adIdx?: number, resize?: (res: any) => { left: number, top: number }) {
            if (adModule.state == AdState.NoAd) {
                debugLog('广告状态设置为了未上线状态，所以不显示')
                return;
            }
            if (!this._info || !this._info.ids.length) {
                debugWarn('未设置banner数据')
                return;
            }
            if (justShowByLongPhone && !this._isLongPhone()) {
                // 如果只在长屏幕手机显示banner，且当前手机是短屏幕，则隐藏banner
                if (this._bannerShowing) {
                    this.hideBannerAd();
                }
                return;
            }
            this._justShowByLongPhone = justShowByLongPhone;
            if (this._bannerShowing) return;
            this._readyShowBanner = true;
            this._crtResize = resize;

            this._setAdIdx(adIdx)

            this._bannerAd = this._getBannerAd(this._info.ids[this._crtAdIdx]);
            this._bannerReadyShow();

        }
        protected _bannerReadyShow() {
            this._bannerShow()
        }
        protected _setAdIdx(adIdx?: number) {
            adIdx = adIdx || 0;

            if (this._crtAdIdx == adIdx) {
                this._crtAdIdx++;
            } else {
                this._crtAdIdx = adIdx;
            }
            if (this._crtAdIdx >= this._info.ids.length) {
                this._crtAdIdx = 0;
            }
        }
        protected _bannerShow() {
            debugLog('准备显示banner', this._readyShowBanner, this._bannerShowing)
            // 如果是没准备要显示的时候，就不显示,防止加载完毕就直接调用显示了
            if (!this._readyShowBanner) return;
            if (this._bannerShowing) return;
            this._bannerAd.show().then(() => {
                debugLog('banner广告显示')
                if (!!this._info.shown) this._info.shown();
            }).catch(err => {
                debugLog('banner广告显示失败了')
                debugLog(err)
            });
            this._bannerShowing = true;
        }
        hideBannerAd(destroy?: boolean) {
            if (!this._info || !this._info.ids || !this._info.ids.length) {
                debugWarn('未设置banner数据')
                return;
            }
            if (!this._bannerAd) return;
            this._readyShowBanner = false;
            debugLog('准备隐藏banner', this._readyShowBanner)

            this._bannerHide(destroy);
        }
        protected _bannerHide(destroy?: boolean) {
            if (destroy) {
                this._destroy();
            } else {
                this._bannerAd.hide()
            }
            this._bannerShowing = false;
            this._crtResize = null
        }

        protected _getBannerAd(obj: IBannerAdObj) {
            if (!this._bannerAd) {
                this._bannerAd = this._createBanner(obj);
                this._bannerAddListener()
            }
            return this._bannerAd;
        }

        protected _getCreateBannerObj(obj: IBannerAdObj) {
            let temp = {
                adUnitId: obj.adUnitId,
                adIntervals: obj.adIntervals,
                style: obj.style || this._getDefStyle()
            }
            return temp;
        }
        protected _createBanner(obj: IBannerAdObj) {
            let temp = this._getCreateBannerObj(obj);
            return wx.createBannerAd(temp);
        }
        protected _bannerAddListener() {
            if (!this._bannerAd) return;
            this._bannerAd.onError(this._onBannerErr.bind(this))
            this._bannerAd.onLoad(this._onBannerLoaded.bind(this))
            this._bannerAd.onResize(this._onBannerResize.bind(this))
        }

        protected _bannerRemoveListener() {
            if (!this._bannerAd) return;
            this._bannerAd.offResize(this._onBannerResize.bind(this))
            this._bannerAd.offError(this._onBannerErr.bind(this))
            this._bannerAd.offLoad(this._onBannerLoaded.bind(this))
        }

        protected _aliveTimeUp() {
            // this._timeKey = -1;
            this._destroy();
            this._bannerShowing = false;
            if (!this._readyShowBanner) return;
            if (this._justShowByLongPhone && !this._isLongPhone()) return;
            timerOnce(16, this, () => {
                this.showBannerAd(this._justShowByLongPhone)
            })
        }

        protected _destroy() {
            if (!this._bannerAd) return;
            if (this._timeKey) {
                clearTimeout(this._timeKey);
                this._timeKey = 0;
            }
            debugLog('call banner destroy')
            this._bannerRemoveListener()
            this._bannerAd.destroy();
            this._bannerAd = null;
            this._bannerLoaded = false;
        }

        protected _onBannerErr(err) {
            debugLog('banner err', err);
            this._bannerLoaded = false;
            this._bannerShowing = false;
            if (!!this._info.bannerErr) this._info.bannerErr(err)
        }
        protected _onBannerLoaded(res) {
            debugLog('banner loaded')
            this._bannerLoaded = true;
            if (!!this._info.loadSuccess) this._info.loadSuccess()
        }
        protected _onBannerResize(res) {
            if (!this._bannerAd) return;
            debugLog('banner resize', res)
            if (!!this._crtResize) {
                let { left, top } = this._crtResize(res);
                this._bannerAd.style.left = left;
                this._bannerAd.style.top = top;
            } else if (!!this._info.resize) {
                let { left, top } = this._info.resize(res);
                this._bannerAd.style.left = left;
                this._bannerAd.style.top = top;
            } else {
                let info = this._getSystemInfoSync();
                let offsetY = this._onIOS() && this._isLongPhone() ? 16 : 0;
                let wid = res.width;
                let hei = res.height
                // let wid = this._info.style && this._info.style.width || res.width;
                // let hei = wid == res.width ? res.height : res.height * (wid / res.width);
                this._bannerAd.style.left = (info.screenWidth - wid) / 2;
                this._bannerAd.style.top = info.screenHeight - hei - offsetY;
                // this._bannerAd.style.realWidth = wid;
                // this._bannerAd.style.realHeight = hei;
                // this._bannerAd.style.width = wid;
                // this._bannerAd.style.height = hei;
            }
        }

        protected _getDefStyle(width?: number, height?: number) {
            let info = this._getSystemInfoSync();
            let offsetY = this._onIOS() && this._isLongPhone() ? 16 : 0;
            let defWidth = width || 300;
            let defHeight = height || 120;
            let style: IBannerStyle = {}
            style.left = (info.screenWidth - defWidth) / 2;
            style.top = info.screenHeight - defHeight - offsetY;
            return style;
        }

    }
}